from functools import partial
from typing import Dict

from PySide6 import QtWidgets
from PySide6.QtGui import QCloseEvent
from PySide6.QtWidgets import QPushButton, QMessageBox

from core.auto_fire import AutoFire
from core.config_manager import ConfigManager
from core.gui.ui_main import Ui_MainWindow
from core.key_codes import code_from_key_name, key_name_from_code
from utils.settings import TITLE


# 改变按钮文字颜色
def change_btn_color(b: QPushButton, status: bool):
    b.setStyleSheet("color: #FF0000;" if status else "")


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle(TITLE)

        # 配置管理器
        self.cm = ConfigManager()
        self.__refresh_config_list()
        # 加载配置
        self.ui.load_config.clicked.connect(self.__load_config)
        # 保存配置
        self.ui.save_config.clicked.connect(self.__save_config)
        # 删除配置
        self.ui.delete_config.clicked.connect(self.__delete_config)

        # 初始化按键映射
        self.code_map: Dict[str, int] = dict()
        self.button_map: Dict[str, QPushButton] = dict()
        self.__init_key_buttons()

        self.tm: AutoFire | None = None
        # 启动按钮
        self.ui.start_button.clicked.connect(self.__start_or_stop)
        # 清空按钮
        self.ui.clean_button.clicked.connect(self.__clean_active_keys)

    # 初始化所有按键
    def __init_key_buttons(self):
        for attr_name in dir(self.ui):
            if not attr_name.startswith('key_'):
                continue

            btn: QPushButton = getattr(self.ui, attr_name)
            if not isinstance(btn, QPushButton):
                continue

            name = attr_name.removeprefix('key_')

            if not (code := code_from_key_name(name)):
                continue

            self.code_map[name] = code
            self.button_map[name] = btn

            if name == "end":
                print(name, self.code_map["end"], self.button_map["end"])


            change_btn_color(btn, code in self.cm.active_keys)
            btn.clicked.connect(partial(self.__event_keyboard, btn, code))

    # 为键盘按键绑定事件
    def __event_keyboard(self, btn: QPushButton, key_code: int):
        print(f"点击按钮: {key_name_from_code(key_code)}, {key_code}")
        if is_enabled := key_code in self.cm.active_keys:
            self.cm.active_keys.remove(key_code)
        else:
            self.cm.active_keys.add(key_code)

        change_btn_color(btn, not is_enabled)

    def closeEvent(self, event: QCloseEvent):
        self.cm.save()

        if self.tm and self.tm.running:
            self.tm.stop()

        event.accept()

    # 刷新界面
    def __refresh_keyboard(self):
        for name, btn in self.button_map.items():
            if code := self.code_map.get(name):
                change_btn_color(btn, code in self.cm.active_keys)

    def __refresh_config_list(self):
        self.ui.config_list.clear()
        self.ui.config_list.addItems(sorted(self.cm.data.keys()))

    def __load_config(self):
        if not (item := self.ui.config_list.currentItem()):
            return

        if not (config_name := item.text()):
            return

        self.ui.config_name.setText(config_name)

        # 如果正在运行，先停止
        if self.tm:
            self.tm.stop()
            self.tm = None
            self.ui.start_button.setText("启动")

        self.cm.change_active_key(config_name)
        self.__refresh_keyboard()

    def __save_config(self):
        config_name = self.ui.config_name.text().strip()
        if not config_name:
            QMessageBox.warning(self, "警告", "请输入配置名称")
            return

        self.cm.data.update({config_name: list(self.cm.active_keys)})
        self.cm.save()
        self.__refresh_config_list()

    def __delete_config(self):
        if not (item := self.ui.config_list.currentItem()):
            return

        if not (config_name := item.text()):
            return

        del self.cm.data[config_name]
        self.cm.save()
        self.__refresh_config_list()

    def __start_or_stop(self):
        if self.tm is None:
            self.tm = AutoFire(self.cm.active_keys)
            self.tm.start()
            self.ui.start_button.setText("停止")
        else:
            self.tm.stop()
            self.tm = None
            self.ui.start_button.setText("启动")


    def __clean_active_keys(self):
        self.cm.active_keys.clear()
        self.__refresh_keyboard()
